from django.db import models
from django.forms.models import ModelForm
from django.forms.widgets import Textarea
import re
from django.core.validators import RegexValidator, MinValueValidator,\
    MaxValueValidator
from mapp.utils.common import AminoAcids


uuid_length = 20
mut_pattern = re.compile("[A-Z]\d+[A-Z]\W*", re.M | re.I)
only_letters = re.compile("[{0}]\d+[{0}]\W*".format(''.join(AminoAcids.list), re.M | re.I))

class Query(models.Model):
    MSA_MAFFT = "mafft"   
    MSA_CLUSTALO = "clustalo"
    MSA_CHOICES = (
            (MSA_MAFFT, "MAFFT"),
            (MSA_CLUSTALO, "CLUSTALO"),
    )
    TREE_FAST = "fasttree"   
    TREE_RAXML = "raxml"
    TREE_CHOICES = (
            (TREE_FAST, "FastTree"),
            (TREE_RAXML, "RAxML"),
    )
    id = models.AutoField(primary_key=True)
    uuid = models.CharField(max_length=uuid_length, db_index=True)
    sequence = models.CharField(max_length=2000)
    mutations = models.CharField(max_length=100000,
                        validators=[RegexValidator(regex=mut_pattern,
                            message="Valid mutations are in <letter><number><letter> format"),
                                    RegexValidator(regex=only_letters,
                            message="Mutations can contain only valid Amino Acid letters")])
    date = models.DateTimeField("query date")
    msa = models.CharField('method of MSA',
                           max_length=20,
                             choices=MSA_CHOICES,
                             default=MSA_MAFFT)
    clusters = models.IntegerField('max number of sequences to be aligned',
                                   default=50,
                                   validators=[MinValueValidator(10),
                                               MaxValueValidator(1000)])
    seqs = models.IntegerField('max number of initial sequences',
                                   default=25000,
                                   validators=[MinValueValidator(10),
                                               MaxValueValidator(35000)])
    tree = models.CharField('method of tree construction',
                           max_length=20,
                             choices=TREE_CHOICES,
                             default=TREE_FAST)
    

    
    def __unicode__(self):
        return self.uuid
    
    def clean(self):
        super(Query, self).clean()
        self.sequence = self.sequence.upper()
        self.mutations = self.mutations.upper()
           
    
class QueryForm(ModelForm):
    class Meta:
        model = Query
        exclude = ['uuid', 'date'] 
        widgets = {
            'sequence': Textarea(attrs={'id': 'sequence_area','name': 'sequence_area',
                                        'spellcheck': 'false'}),
            'mutations' : Textarea(attrs={'id': 'mutations', 'spellcheck': 'false'}),
        }
    
    def clean_sequence(self):
        sequence = self.cleaned_data['sequence']
        sequence = re.sub(ur'>.*?[\r\n]+', '', sequence)
        sequence = re.sub(ur'[\r\n]', '', sequence).upper()
        if not re.match('^[%s]+$' % ''.join(AminoAcids.list), sequence, flags=re.I):
            wrong_letters = ', '.join([ c for c in sequence if c.upper() not in AminoAcids.list])
            self._errors["sequence"] =  self.error_class(['Wrong letter in sequence: %s' % wrong_letters])
            del self.cleaned_data['sequence']
        return sequence
    
    def clean_mutations(self):
        muts = self.cleaned_data['mutations'].upper()
        
        return muts